Distinct subsequences

Time: O(N^2); Space: O(N); hard

Given a string S and a string T, count the number of distinct subsequences of S which equals T.

A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, “ACE” is a subsequence of “ABCDE” while “AEC” is not).

It’s guaranteed the answer fits on a 32-bit signed integer.

Example 1:

Input: S = “rabbbit”, T = “rabbit”

Output: 3

Explanation:

  • As shown below, there are 3 ways you can generate “rabbit” from S.

  • (The caret symbol ^ means the chosen letters)

    rabbbit
    ^^^^ ^^
    rabbbit
    ^^ ^^^^
    rabbbit
    ^^^ ^^^
    
  • You could remove any ‘b’ in S, so there are 3 ways to get T.

Example 2:

Input: S = “babgbag”, T = “bag”

Output: 5

Explanation:

  • As shown below, there are 5 ways you can generate “bag” from S.

  • (The caret symbol ^ means the chosen letters)

    babgbag
    ^^ ^
    babgbag
    ^^    ^
    babgbag
    ^    ^^
    babgbag
      ^  ^^
    babgbag
        ^^^
    

Example 3:

Input: S = “abcd”, T = “”

Output: 1

Explanation:

  • There is only 1 way to get T - remove all chars in S.

[3]:
class Solution1(object):
    """
    Time: O(N^2)
    Space: O(N)
    """
    def numDistinct(self, S, T):
        """
        :type S: str
        :type T: str
        :rtype: an integer
        """
        ways = [0 for _ in range(len(T) + 1)]
        ways[0] = 1

        for S_char in S:
            for j, T_char in reversed(list(enumerate(T))):
                if S_char == T_char:
                    ways[j + 1] += ways[j]

        return ways[len(T)]
[4]:
s = Solution1()

S = "rabbbit"
T = "rabbit"
assert s.numDistinct(S, T) == 3

S = "babgbag"
T = "bag"
assert s.numDistinct(S, T) == 5

S = "abcd"
T = ""
assert s.numDistinct(S, T) == 1